#include "meshcontainer.h"

CMeshContainer::~CMeshContainer()
{
    /**
     * Destructor, ensure that the memory is freed back to the heap.
     */
    clearMeshes();
}

CMeshContainer* CMeshContainer::getInstance()
{
    /**
     * Obtains the single static instance of the container. This attempts to
     * create an instance of this object if it doesn't exist. If it already
     * exists, then return the address of this instance. This uses the
     * singleton methodology.
     * 
     * @static
     * @return CMeshContainer* A pointer to the static singleton of the 
     *                          container
     */
    static CMeshContainer instance;
    return &instance;
}
        
CMesh* CMeshContainer::addMesh(string key)
{
    /**
     * Adds a mesh into the container. This dynamically creates memory on the
     * heap and saves it for reference.
     *
     * @param string key The reference ID of the mesh
     * @return CLight* The address of the newely created mesh.
     */
    CMesh *pMesh = new CMesh;
    if (pMesh)
    {
        m_Container.insert(pair<string, CMesh*>(key, pMesh));
        return pMesh;
    }
    stringstream sstream;
    sstream << "Could not allocate enough memory to create the mesh: "
            << key;
    MessageBox(NULL, sstream.str().c_str(), "CMeshContainer::addMesh", MB_OK);
    return nullptr;
}

bool CMeshContainer::removeMesh(string key)
{
    /**
     * Removes the mesh from reference if it exists and clears the memory.
     *
     * @param string key The name of the mesh to remove.
     * @return bool Whether or not it was successfully removed.
     */
    map<string,CMesh*>::iterator i = m_Container.find(key);
    if (i == m_Container.end())
    {
        return false;
    }

    delete i->second;
    m_Container.erase(i);

    return true;
}

CMesh* CMeshContainer::getMesh(string key)
{
    /**
     * Obtain the mesh object if the key exists, otherwise return a nullptr.
     *
     * @param string key The name of the mesh to obtain
     * @return CLight* A pointer to the mesh, nullptr if cannot be found.
     */
    map<string,CMesh*>::iterator i = m_Container.find(key);
    if (i == m_Container.end())
    {
        return nullptr;
    }
    return i->second;
}

void CMeshContainer::clearMeshes()
{
    /**
     * Clears all textures from memory and resets the container. This should
     * be called at map unload to unload all the textures.
     */
    if (m_Container.size() > 0)
    {
        for (map<string,CMesh*>::iterator i = m_Container.begin(); 
                i != m_Container.end(); ++i)
        {
            delete i->second;
        }
        m_Container.clear();
    }
}